package org.stone.project.securityInterface.aop;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.stone.project.common.pojo.exception.BuzException;
import org.stone.project.common.pojo.exception.ServiceException;
import org.stone.project.common.pojo.sysEnum.SystemCodeEnum;
import org.stone.project.securityInterface.annotation.PermissionCheck;
import org.stone.project.securityInterface.pojo.dto.PermissionAnnotationDto;
import org.stone.project.securityInterface.pojo.dto.UserInfoDto;
import org.stone.project.securityInterface.service.UserInfoService;
import org.stone.project.securityInterface.utils.PermissionAnnotationCheckUtil;

@Aspect
@Component
public class PermissionCheckConfig {
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 鉴权注解增强
     * @return
     */
    @SneakyThrows
    @Around(value = "@annotation(permissionCheck)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, PermissionCheck permissionCheck){
        //获取参数
        Object[] args = joinPoint.getArgs();
        PermissionAnnotationDto permissionDto = PermissionAnnotationCheckUtil.getPermissionDto(permissionCheck.value());
        if (ObjectUtil.isNotNull(permissionDto)){
            UserInfoDto userInfoDto = userInfoService.getUserInfoDto();
            if ((Boolean) (ReflectUtil.invokeStatic(permissionDto.getMethod(), permissionDto.getParams().toArray(), userInfoDto))){
                return joinPoint.proceed(args);
            }else{
                String info = "权限不足,权限资源为" + permissionDto.getAnnotationStr() + ",用户信息为" + userInfoDto.getUserKey();
                throw new ServiceException(SystemCodeEnum.FORBIDDEN,info);
            }
        }
        throw new BuzException("注解标记权限不存在,名称为"+permissionCheck.value());
    }
}
